package com.lcf.app.jwt.config;

import cn.hutool.core.util.StrUtil;
import com.lcf.app.jwt.common.Current;
import com.lcf.app.jwt.common.CurrentUser;
import com.lcf.app.jwt.interceptor.JwtTokenInterceptor;
import com.lcf.app.jwt.model.User;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

/**
 * @author ChenFei
 * @date 2022/1/18
 */
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {

    private final JwtTokenInterceptor jwtTokenInterceptor;
    private final JwtHelper jwtHelper;

    //配置拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtTokenInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(jwtHelper.getExcludePath());
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new MyHandlerMethodArgumentResolver());
    }

    /**
     * 自定义参数处理器
     */
    private class MyHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

        @Override
        public boolean supportsParameter(MethodParameter parameter) {
            //参数有user类型并且参数注解为Current
            return User.class.equals(parameter.getParameter().getType()) && parameter.hasParameterAnnotation(Current.class);
        }

        @Override
        public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
            //如果header存在token，并且满足上边的条件（supportsParameter）
            String tokenHeader = webRequest.getHeader(jwtHelper.getHeaderName());
            User user = null;
            if (StrUtil.isNotBlank(tokenHeader)) {
                try {
                    user = jwtHelper.verify(tokenHeader, User.class);
                    CurrentUser.set(user);
                } catch (Exception e) {

                }
            }
            return user;
        }
    }

}
